package cn.tk.service.mr.impl;

import cn.tk.cache.mr.EntityBuf;
import cn.tk.cache.mr.FlowBuf;
import cn.tk.cache.mr.IntentBuf;
import cn.tk.cache.mr.VariableBuf;
import cn.tk.model.entity.mr.FlowNode;
import cn.tk.model.pojo.mr.flow.ConditionDTO;
import cn.tk.model.pojo.mr.flow.ConditionNodeCollect;
import cn.tk.model.pojo.mr.flow.ConditionNodeDTO;
import cn.tk.service.mr.ConditionNodeService;
import cn.tk.utils.EmptyUtil;
import cn.tk.utils.JpaMapper;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by denglw on 2021/8/2.<br/>
 * Desc: 条件节点  服务实现层
 */
@Service
public class ConditionNodeServiceImpl implements ConditionNodeService {

    @Autowired
    private JpaMapper jpaMapper;

    @Override
    public List<ConditionNodeDTO> recoverableConditionNodes(Long botId) {
        FlowBuf flowBuf = FlowBuf.getInstance();
        List<FlowNode> botNodes = flowBuf.botNodes(botId);
        // 找出其中的条件节点id列表
        List<Long> conditionNodeIds = botNodes.stream().filter(i ->
                Objects.equals(i.getType(), 2)).map(FlowNode::getId).collect(Collectors.toList());
        List<ConditionNodeDTO> dtos = this.conditionNodes(conditionNodeIds);
        // 返回可打断恢复的节点
        return dtos.stream().filter(i -> Objects.equals(i.getRecoverable(), true)).collect(Collectors.toList());
    }

    @Override
    public List<ConditionNodeDTO> conditionNodes(List<Long> conditionNodeIds) {
        List<ConditionNodeDTO> dtos = this.baseConditionNodes(conditionNodeIds);
        if (EmptyUtil.emptyColl(dtos)) {
            return new ArrayList<>();
        }
        // 填充条件项
        List<ConditionDTO> conditions = this.conditions(conditionNodeIds);
        conditions.stream().collect(Collectors.groupingBy(ConditionDTO::getNodeId)).forEach((k, v) -> {
            for (ConditionNodeDTO dto : dtos) {
                boolean match = Objects.equals(dto.getNodeId(), k);
                if (match) {
                    dto.setConditions(v);
                }
            }
        });
        // 填充信息采集项
        List<ConditionNodeCollect> collects = this.conditionNodeCollects(conditionNodeIds);
        collects.stream().collect(Collectors.groupingBy(ConditionNodeCollect::getNodeId)).forEach((k, v) -> {
            for (ConditionNodeDTO dto : dtos) {
                boolean match = Objects.equals(dto.getNodeId(), k);
                if (match) {
                    dto.setConditionNodeCollects(v);
                }
            }
        });
        return dtos;
    }

    @Override
    public ConditionNodeDTO conditionNode(Long conditionNodeId) {
        if (EmptyUtil.nullOrZero(conditionNodeId)) {
            return null;
        }
        List<ConditionNodeDTO> dtos = this.conditionNodes(Lists.newArrayList(conditionNodeId));
        return EmptyUtil.emptyColl(dtos) ? null : dtos.get(0);
    }

    private List<ConditionNodeDTO> baseConditionNodes(List<Long> nodeIds) {
        String sql = "select a.flow_id flowId, b.id nodeId, b.recoverable, b.union_rule unionRule\n" +
                "from mr_bot_flow_node a, mr_flow_condition_node b\n" +
                "where a.id=b.id and a.id in (:nodeIds) and a.deleted=0 and a.disabled=0";
        Map<String, Object> params = new HashMap<>(4);
        params.put("nodeIds", nodeIds);
        Class<?>[] clazzes = new Class[]{Long.class, Long.class, Boolean.class, Integer.class};
        return jpaMapper.queryList(sql, params, ConditionNodeDTO.class, clazzes);
    }

    private List<ConditionDTO> conditions(List<Long> nodeIds) {
        String sql = "select id conditionId, flow_node_id nodeId, type, intent_id intentId,\n" +
                "entity_id entityId, entity_value_rule entityValueRule, entity_value entityValue,\n" +
                "variable_id variableId, variable_rule variableRule, variable_value variableValue\n" +
                "from mr_flow_condition where flow_node_id in (:nodeIds)";
        Map<String, Object> params = new HashMap<>(4);
        params.put("nodeIds", nodeIds);
        Class<?>[] clazzes = new Class[]{Long.class, Long.class, Integer.class,
                Long.class, Long.class, Integer.class, String.class, Long.class, Integer.class, String.class};
        List<ConditionDTO> dtos = jpaMapper.queryList(sql, params, ConditionDTO.class, clazzes);
        if (EmptyUtil.emptyColl(dtos)) {
            return new ArrayList<>();
        }
        // 根据缓存，匹配意图码、实体码、变量码
        IntentBuf intentBuf = IntentBuf.getInstance();
        EntityBuf entityBuf = EntityBuf.getInstance();
        VariableBuf variableBuf = VariableBuf.getInstance();
        for (ConditionDTO dto : dtos) {
            dto.setIntentCode(intentBuf.getCode(dto.getIntentId()));
            dto.setEntityCode(entityBuf.getCode(dto.getEntityId()));
            dto.setVariableEnName(variableBuf.getEnName(dto.getVariableId()));
        }
        return dtos;
    }

    private List<ConditionNodeCollect> conditionNodeCollects(List<Long> nodeIds) {
        String sql = "select flow_node_id nodeId, code, name, value from mr_flow_condition_node_collect where flow_node_id in (:nodeIds)";
        Map<String, Object> params = new HashMap<>(4);
        params.put("nodeIds", nodeIds);
        Class<?>[] clazzes = new Class[]{Long.class, String.class, String.class, String.class};
        return jpaMapper.queryList(sql, params, ConditionNodeCollect.class, clazzes);
    }

}
